package jktime

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"time"
)

/*
 * 1. Year - month - day
 * 2. Month - day
 * 3. Week
 * 4. hour - minute - second
 * - only once, one time (year-m-d-h-min-s)
 * -
 */

type TimeItem struct {
	Year   int `json:"year"`
	Month  int `json:"month"`
	Day    int `json:"day"`
	Hour   int `json:"hour"`
	Minute int `json:"minute"`
	Second int `json:"second"`
}

type TimeItems struct {
	Start TimeItem `json:"startTime"`
	End   TimeItem `json:"endTime"`
	Week  []int    `json:"week"` // monday start 1-7
}

type TimeCompare struct {
	Items []TimeItems
}

func NewTimeCompare(timestr string) (*TimeCompare, error) {
	l := &TimeCompare{}
	err := json.Unmarshal([]byte(timestr), &l.Items)
	if err != nil {
		return nil, err
	}
	return l, nil
}

func NewTimeCompareFile(filename string) (*TimeCompare, error) {
	d, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	l := &TimeCompare{}
	err = json.Unmarshal(d, &l.Items)
	if err != nil {
		return nil, err
	}
	return l, nil
}

func (tc *TimeCompare) inNow(item TimeItems, now time.Time) bool {
	if item.Start.Year != -1 && item.End.Year != -1 {
		if now.Year() < item.Start.Year || now.Year() > item.End.Year {
			return false
		}
	}
	if item.Start.Month != -1 && item.End.Month != -1 {
		if int(now.Month()) < item.Start.Month || int(now.Month()) > item.End.Month {
			return false
		}
	}
	if item.Start.Day != -1 && item.End.Day != -1 {
		if now.Day() < item.Start.Day || now.Day() > item.End.Day {
			return false
		}
	}
	if len(item.Week) > 0 {
		week := now.Weekday()
		if week == time.Sunday {
			week = 7
		}
		find := false
		for _, v := range item.Week {
			if v == -1 {
				continue
			}
			if int(week) == v {
				find = true
				break
			}
		}
		if !find {
			return false
		}
	}
	if item.Start.Hour != -1 && item.End.Hour != -1 {
		if now.Hour() < item.Start.Hour || now.Hour() > item.End.Hour {
			return false
		}
	}
	if item.Start.Minute != -1 && item.End.Minute != -1 {
		if now.Minute() < item.Start.Minute || now.Minute() > item.End.Minute {
			return false
		}
	}
	if item.Start.Second != -1 && item.End.Second != -1 {
		if now.Second() < item.Start.Second || now.Second() > item.End.Second {
			return false
		}
	}

	return true
}

func (tc *TimeCompare) InNow() bool {
	for _, v := range tc.Items {
		t := tc.inNow(v, time.Now())
		if t {
			return true
		}
	}
	return false
}

func (tc *TimeCompare) InTime(tm time.Time) bool {
	for _, v := range tc.Items {
		t := tc.inNow(v, tm)
		if t {
			return true
		}
	}
	return false
}

func (tc *TimeCompare) DebugPrint() string {
	str := ""
	for k, v := range tc.Items {
		s := fmt.Sprintf("[%d][%04d/%02d/%02d %02d:%02d:%02d] - [%04d/%02d/%02d %02d:%02d:%02d]",
			k, v.Start.Year, v.Start.Month, v.Start.Day, v.Start.Hour, v.Start.Minute, v.Start.Second,
			v.End.Year, v.End.Month, v.End.Day, v.End.Hour, v.End.Minute, v.End.Second)
		str += s
		str += "["
		for _, t := range v.Week {
			s = fmt.Sprintf("%d", t)
			str += s
		}
		str += "]\n"
	}
	return str
}
